import type { ActionType, ProColumns } from '@ant-design/pro-table';
import { Button, Popconfirm, Space, Table, Tag, message, Input, Tree, Card, Avatar } from 'antd';
import { CheckCircleOutlined, DownOutlined, FolderOutlined, MenuFoldOutlined, MinusCircleOutlined, TeamOutlined, UserOutlined } from '@ant-design/icons';
import {
  deleteApiUser as Delete,
  getApiUserDetailById as GetDetail,
  postApiUserByIndexByLimitPagedList as PagedList,
  getApiUserByIdPermissions as GetPermissions,
  patchApiUserByIdUpdataPasswordByNewpassword as PasswordChange,
} from '@/services/furion-cms/user';
import {
  getApiOrganizationTree as GetOrgs,
} from '@/services/furion-cms/organization';
import React, { useEffect, useRef, useState } from 'react';
import {
  ProFormText
} from '@ant-design/pro-form';
import DetailViewer from './components/personDetail';
import { PageContainer } from '@ant-design/pro-layout';
import ProTable from '@ant-design/pro-table';
import styles from './index.less';
import { useIntl } from 'umi';
import PermissionsDefinition from '@/permissionsDefinition';
import PersonPermission from './components/personPermission';
import type { DataNode } from 'antd/lib/tree';
import { PopupChangePassword } from '@/components/ChangePassword';
import { useCustomAccess } from '@/components/CustomAccess';

const formattedDataHandle = (inputs: API.OrgDto[]): DataNode[] => {
  return inputs.map(m => ({ icon: <FolderOutlined />, title: m.name!, key: m.id!, children: formattedDataHandle(m.children ?? []) }));
}

const UserManager: React.FC = () => {

  const actionRef = useRef<ActionType>();
  const AccessButton = useCustomAccess(Button);
  const AccessConfirm = useCustomAccess(Popconfirm);
  /**
   * @en-US International configuration
   * @zh-CN 国际化配置
   * */
  const intl = useIntl();

  const [details, setDetails] = useState<API.UserDetailDto>();
  const [permissions, setPermissions] = useState<Partial<API.UserDto & { permissions: string[] }>>();
  const [detailModalVisible, handleDetailModalVisible] = useState(false);
  const [permissionModalVisible, handlePermissionModalVisible] = useState(false);
  const [passwordChangeVisible, setPasswordChangeVisible] = useState(false);
  const [tableRow, setTableRow] = useState<API.UserDto>();
  const [tableParams, setTableParmas] = useState<Record<string, any>>();
  const [treeData, setTreeData] = useState<DataNode[]>([]);
  const [orgTreeVisible, setOrgTreeVisible] = useState(false);
  const [selectedOrg, setSelectedOrg] = useState<DataNode>();

  const [loadingVisible, handelLoadingVisible] = useState(false);

  useEffect(() => {
    (async () => {
      try {
        const { data } = await GetOrgs({});
        setTreeData([{ icon: <FolderOutlined />, title: '全部人员', key: 0 }, ...formattedDataHandle(data ?? [])]);
      } catch { }
    })();
  }, []);

  const getDetail = async (id: number) => {
    handelLoadingVisible(true);
    try {
      const { data } = await GetDetail({ id });
      setDetails(data);
      handleDetailModalVisible(true);
    } catch { }
    handelLoadingVisible(false);
  }

  const getPermissions = async (row: API.UserDto) => {
    handelLoadingVisible(true);
    try {
      const { data } = await GetPermissions({ id: row.id! });
      setPermissions({ ...row, permissions: data ?? [] });
      handlePermissionModalVisible(true);
    } catch { }
    handelLoadingVisible(false);
  }

  const handleDeleteConfirm = async (idList: any[]) => {
    handelLoadingVisible(true);
    try {
      await Delete(idList);
      message.success('删除操作成功');
      actionRef.current?.reload();
    } catch (error) { }
    handelLoadingVisible(false);
  }

  const handleOrgTreeSelected = (_: any, { node, selectedNodes }: any) => {
    const loopOrgId = (nodes: DataNode[]) => {
      let orgIdList: string[] = [];
      nodes.forEach(({ key, children }) => {
        if (key !== 0) orgIdList = [...orgIdList, key as string, ...loopOrgId(children ?? [])];
      });
      return orgIdList;
    }
    if (node.key !== 0) setSelectedOrg(node);
    else setSelectedOrg(undefined);
    setTableParmas({ ...tableParams, orgIds: loopOrgId(selectedNodes) });
    console.log('selected tree', node, selectedNodes);
  }

  const columns: ProColumns<API.UserDto>[] = [
    {
      title: intl.formatMessage({
        id: 'pages.user.nickName',
        defaultMessage: '昵称'
      }),
      dataIndex: 'nickName',
      search: false,
      render: (dom, entity) => {
        return <Space><Avatar size={24} icon={<UserOutlined />} src={entity.avatar} />{dom}</Space>
      }
    },
    {
      title: intl.formatMessage({
        id: 'pages.user.gender',
        defaultMessage: '性别'
      }),
      sorter: true,
      dataIndex: 'gender',
      renderText: (val: number) => ['未知', '男', '女'][val],
      search: false
    },
    {
      title: intl.formatMessage({
        id: 'pages.user.email',
        defaultMessage: '电子邮件'
      }),
      dataIndex: 'email',
      search: false,
    },
    {
      title: intl.formatMessage({
        id: 'pages.user.phoneNumber',
        defaultMessage: '手机号'
      }),
      dataIndex: 'phoneNumber',
      search: false,
    },
    {
      title: intl.formatMessage({
        id: 'pages.user.status',
        defaultMessage: '状态'
      }),
      dataIndex: 'status',
      search: false,
      render: (dom, entity) => [
        (entity.enable && <Tag key="success" icon={<CheckCircleOutlined />} color="success">{entity.status}</Tag>),
        (!entity.enable && <Tag key="error" icon={<MinusCircleOutlined />} color="error">{entity.status}</Tag>)
      ]
    },
    {
      title: intl.formatMessage({
        id: 'pages.user.createdTime',
        defaultMessage: '创建时间'
      }),
      dataIndex: 'createdTime',
      valueType: 'dateRange',
      sorter: true,
      width: 180,
      render: (dom, entity) => {
        return entity.createdTime;
      }
    },
    {
      title: intl.formatMessage({
        id: 'pages.searchTable.titleOption',
        defaultMessage: '操作'
      }),
      dataIndex: 'option',
      valueType: 'option',
      width: 250,
      render: (_, record) => [
        <AccessButton key="update"
          code={PermissionsDefinition.Person.UpdateUser}
          type="link" size="small"
          onClick={() => getDetail(record.id!)}>
          {intl.formatMessage({
            id: 'pages.common.update',
            defaultMessage: '编辑'
          })}
        </AccessButton>,
        <AccessButton key="passport"
          code={PermissionsDefinition.Person.PasswordReset}
          type="link" size="small"
          onClick={() => {
            setPasswordChangeVisible(true);
            setTableRow(record);
          }}>
          {intl.formatMessage({
            id: 'pages.user.passwordChange',
            defaultMessage: '密码变更'
          })}
        </AccessButton>,
        <AccessButton key="permission"
          code={PermissionsDefinition.Person.PermissionAssign}
          type="link" size="small"
          onClick={() => getPermissions(record!)}>
          {intl.formatMessage({
            id: 'pages.user.permission',
            defaultMessage: '权限'
          })}
        </AccessButton>,
        <AccessConfirm key="delete"
          code={PermissionsDefinition.Person.DeleteUser}
          disabled={record.hasSeed}
          title={intl.formatMessage({
            id: 'pages.common.delete.confirm',
            defaultMessage: '您是否确认将「{name}」删除?'
          }, {
            name: record.nickName
          })}
          onConfirm={() => handleDeleteConfirm([record.id!])}
        >
          <Button disabled={record.hasSeed} type="link" size="small"
          >{intl.formatMessage({
            id: 'pages.common.delete',
            defaultMessage: '删除'
          })}</Button>
        </AccessConfirm>
      ],
    },
  ];

  return (
    <PageContainer className={styles.main}
      breadcrumbRender={false}>
      <ProTable<API.UserDto>
        actionRef={actionRef}
        loading={loadingVisible}
        rowKey="id"
        search={{ filterType: "light" }}
        pagination={{
          pageSize: 10,
          showSizeChanger:true
        }}
        options={{
          search: false,
        }}
        headerTitle={<Space>
          <Button type="text" icon={orgTreeVisible ? <MenuFoldOutlined /> : <TeamOutlined />}
            onClick={async () => {
              setOrgTreeVisible(!orgTreeVisible);
            }} />
          <Input.Search
            addonBefore={(!orgTreeVisible && selectedOrg) ?
              <Tag
                style={{
                  margin: 0,
                  padding: 0,
                  backgroundColor: 'transparent',
                  border: 'none'
                }}
                onClose={() => {
                  setSelectedOrg(undefined);
                  setTableParmas({ ...tableParams, orgIds: [] });
                }} closable>
                {selectedOrg?.title}
              </Tag> : undefined}
            onSearch={(value) => setTableParmas({
              ...tableParams,
              keyword: value
            })} allowClear />
        </Space>}
        tableRender={(_, dom) => (<div
          style={{
            display: 'flex',
            width: '100%',
          }}
        >
          <Card title={intl.formatMessage({
            id: 'pages.org.tree',
            defaultMessage: "组织机构树"
          })}
            className={styles.orgTreeCard}
            style={{
              width: orgTreeVisible ? 240 : 0,
              opacity: orgTreeVisible ? 1 : 0,
            }}>
            {treeData.length && <Tree
              switcherIcon={<DownOutlined />}
              treeData={treeData}
              defaultSelectedKeys={[0]}
              onSelect={handleOrgTreeSelected}
              style={{
                width: 192
              }}
              showIcon
              defaultExpandAll
              blockNode />}
          </Card>
          <div
            style={{
              flex: 1,
            }}
          >
            {dom}
          </div>
        </div>)}
        params={{ ...tableParams }}
        request={async (params, sort, filter) => {
          // 表单搜索项会从 params 传入，传递给后端接口。
          console.log(params, sort, filter);
          handelLoadingVisible(true);
          // 转换固定的参数
          const { current, pageSize, createdTime } = params;
          const [StartTime, EndTime] = createdTime || [];
          // 删除无效参数
          delete params.current;
          delete params.pageSize;
          delete params.createdTime;
          // 发起请求
          return PagedList({
            index: (current || 1),
            limit: (pageSize || 10),
            StartTime,
            EndTime,
            ...params
          }, sort).then(result => {
            const { list: data, total } = result.data || {};
            return {
              data,
              success: result.success,
              total
            }
          }).finally(() => handelLoadingVisible(false));
        }}
        columns={columns}
        toolBarRender={() => [
          <AccessButton code={PermissionsDefinition.Person.CreateUser}
            type="primary" key="create"
            onClick={() => {
              setDetails(undefined);
              handleDetailModalVisible(true);
            }}>
            {intl.formatMessage({
              id: 'pages.user.create',
              defaultMessage: '创建用户'
            })}
          </AccessButton>,
        ]}
        rowSelection={{
          selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT],
        }}
        tableAlertOptionRender={({ selectedRowKeys, onCleanSelected }) => {
          return (
            <Space size={16}>
              <AccessConfirm key="batchDelete"
                code={PermissionsDefinition.Person.DeleteUser}
                title={intl.formatMessage({
                  id: 'pages.common.batchDeletion.confirm',
                  defaultMessage: '您是否确认删除选中的「{count}」项数据?'
                }, { count: selectedRowKeys.length })}
                onConfirm={() => {
                  handleDeleteConfirm(selectedRowKeys)
                  onCleanSelected()
                }}
              >
                <a href="#">{intl.formatMessage({
                  id: 'pages.common.batchDeletion',
                  defaultMessage: '批量删除'
                })}</a>
              </AccessConfirm>
              <a onClick={() => message.warning('未实现')}>{intl.formatMessage({
                id: 'pages.common.batchExport',
                defaultMessage: '导出数据'
              })}</a>
            </Space>
          );
        }}
      />
      <DetailViewer key="addOrUpdate"
        recored={details}
        modalVisible={detailModalVisible}
        onVisibleChange={handleDetailModalVisible}
        onUpdate={() => actionRef.current?.reload()}
      />
      <PersonPermission key="setPersonPermission"
        recored={permissions}
        modalVisible={permissionModalVisible}
        onVisibleChange={handlePermissionModalVisible}
        modalProps={{
          closable: false
        }}
      />
      <PopupChangePassword
        modalVisible={passwordChangeVisible}
        onVisibleChange={setPasswordChangeVisible}
        initialValues={tableRow}
        onSubmit={values => {
          console.log('password-change', values);
          return PasswordChange({
            id: values.id!,
            newpassword: values.newPassword!
          }).then(() => {
            message.success(intl.formatMessage({
              id: 'pages.user.passwordchange.success',
              defaultMessage: '密码修改成功'
            }));
            setTableRow(undefined);
            setPasswordChangeVisible(false);
          });
        }}
      >
        <ProFormText name="id" hidden />
      </PopupChangePassword>
    </PageContainer>
  );
};

export default UserManager;
